<?php
/**
 * ShopEx licence
 *
 * @copyright  Copyright (c) 2005-2010 ShopEx Technologies Inc. (http://www.shopex.cn)
 * @license  http://ecos.shopex.cn/ ShopEx License
 */

/**
* 登录统一调用的类，该类执行验证已经验证后的跳转
*/
class pam_callback{

	/**
	* 登录调用的方法
	* @param array $params 认证传递的参数,包含认证类型，跳转地址等
	*/
    function login($params){
        $this->removeXSS1($params['module']);//过滤xss攻击
        $auth = pam_auth::instance($params['type']);
        $auth->set_appid($params['appid']);
        try{
            class_exists($params['module']);
        }catch (Exception $e){
            kernel::single('site_router')->http_status('p404');
        }
        if($params['module']){
            if(class_exists($params['module']) && ($passport_module = kernel::single($params['module']))){
                if($passport_module instanceof pam_interface_passport){
                    $module_uid = $passport_module->login($auth,$auth_data);
                    if($module_uid){
                        $auth_data['account_type'] = $params['type'];
                        $auth->account()->update($params['module'], $module_uid, $auth_data);
                    }
                    $log = array(
                        'event_time'=>time(),
                        'event_type'=>$auth->type,
                        'event_data'=>base_request::get_remote_addr().':'.$auth_data['log_data'].':'.$_SERVER['HTTP_REFERER'],

                    );
                    app::get('pam')->model('log')->insert($log);
                    if(!$module_uid)$_SESSION['last_error'] = $auth_data['log_data'];
                    $_SESSION['type'] = $auth->type;
                    $_SESSION['login_time'] = time();
                    $params['member_id'] = $_SESSION['account'][$params['type']];
                    $params['uname'] = $_POST['uname'];
                    foreach(kernel::servicelist('pam_login_listener') as $service)
                    {
                        $service->listener_login($params);
                    }
                    if($params['redirect'] && $module_uid){
                        $service = kernel::service('callback_infomation');
                        if(is_object($service)){
                            if(method_exists($service,'get_callback_infomation') && $module_uid){
                                $data = $service->get_callback_infomation($module_uid,$params['type']);
                                if(!$data) $url = '';
                                else $url = '?'.utils::http_build_query($data);
                            }

                        }
                    }

                    if($_COOKIE['autologin'] > 0){
                        kernel::single('base_session')->set_cookie_expires($_COOKIE['autologin']);
                        //如果自动登录，设置cookie过期时间，单位：分
                    }

                    if($_SESSION['callback'] && !$module_uid){
                        $callback_url = $_SESSION['callback'];
                        unset($_SESSION['callback']);
                        header('Location:' .urldecode($callback_url));
                        exit;
                    }
                     else{
                          header('Location:' .base64_decode(str_replace('%2F','/',urldecode($params['redirect']))). $url);
                          exit;
                     }

                }
            }else{

            }
        }
    }
    function removeXSS1(&$val) {
         // remove all non-printable characters. CR(0a) and LF(0b) and TAB(9) are allowed
         // this prevents some character re-spacing such as <java\0script>
         // note that you have to handle splits with \n, \r, and \t later since they *are* allowed in some inputs
         $val = preg_replace('/([\x00-\x08][\x0b-\x0c][\x0e-\x20])/', '', $val);

         //REMOVE SQL INJECTION
         $val = preg_replace(sql_regcase("/(\n|\r|%0a|%0d|Content-Type:|bcc:|to:|cc:|Autoreply:|from|select|insert|truncate|delete|where|drop table|show tables|#|\*|--|\\\\)/"), "", $val);

         // straight replacements, the user should never need these since they're normal characters
         // this prevents like <IMG SRC=&#X40&#X61&#X76&#X61&#X73&#X63&#X72&#X69&#X70&#X74&#X3A&#X61&#X6C&#X65&#X72&#X74&#X28&#X27&#X58&#X53&#X53&#X27&#X29>
         $search = 'abcdefghijklmnopqrstuvwxyz';
         $search.= 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
         $search.= '1234567890!@#$%^&*()';
         $search.= '~`";:?+/={}[]-_|\'\\';

         for ($i = 0; $i < strlen($search); $i++) {
             // ;? matches the ;, which is optional
             // 0{0,7} matches any padded zeros, which are optional and go up to 8 chars
             // &#x0040 @ search for the hex values
             $val = preg_replace('/(&#[x|X]0{0,8}'.dechex(ord($search[$i])).';?)/i', $search[$i], $val); // with a ;
             // &#00064 @ 0{0,7} matches '0' zero to seven times
             $val = preg_replace('/(&#0{0,8}'.ord($search[$i]).';?)/', $search[$i], $val); // with a ;
         }

         // now the only remaining whitespace attacks are \t, \n, and \r
        $ra1 = Array('javascript', 'vbscript', 'expression', 'applet', 'meta', 'xml', 'blink', 'link', 'style', 'script', 'embed', 'object', 'iframe', 'frame', 'frameset', 'ilayer', 'layer', 'bgsound', 'title', 'base');
        $ra2 = Array('onabort', 'onactivate', 'onafterprint', 'onafterupdate', 'onbeforeactivate', 'onbeforecopy', 'onbeforecut', 'onbeforedeactivate', 'onbeforeeditfocus', 'onbeforepaste', 'onbeforeprint', 'onbeforeunload', 'onbeforeupdate', 'onblur', 'onbounce', 'oncellchange', 'onchange', 'onclick', 'oncontextmenu', 'oncontrolselect', 'oncopy', 'oncut', 'ondataavailable', 'ondatasetchanged', 'ondatasetcomplete', 'ondblclick', 'ondeactivate', 'ondrag', 'ondragend', 'ondragenter', 'ondragleave', 'ondragover', 'ondragstart', 'ondrop', 'onerror', 'onerrorupdate', 'onfilterchange', 'onfinish', 'onfocus', 'onfocusin', 'onfocusout', 'onhelp', 'onkeydown', 'onkeypress', 'onkeyup', 'onlayoutcomplete', 'onload', 'onlosecapture', 'onmousedown', 'onmouseenter', 'onmouseleave', 'onmousemove', 'onmouseout', 'onmouseover', 'onmouseup', 'onmousewheel', 'onmove', 'onmoveend', 'onmovestart', 'onpaste', 'onpropertychange', 'onreadystatechange', 'onreset', 'onresize', 'onresizeend', 'onresizestart', 'onrowenter', 'onrowexit', 'onrowsdelete', 'onrowsinserted', 'onscroll', 'onselect', 'onselectionchange', 'onselectstart', 'onstart', 'onstop', 'onsubmit', 'onunload');
         $ra = array_merge($ra1, $ra2);

         $found = true; // keep replacing as long as the previous round replaced something
         while ($found == true) {
             $val_before = $val;
             for ($i = 0; $i < sizeof($ra); $i++) {
                 $pattern = '/';
                 for ($j = 0; $j < strlen($ra[$i]); $j++) {
                     if ($j > 0) {
                         $pattern .= '(';
                         $pattern .= '(&#[x|X]0{0,8}([9][a][b]);?)?';
                         $pattern .= '|(&#0{0,8}([9][10][13]);?)?';
                         $pattern .= ')?';
                     }
                     $pattern .= $ra[$i][$j];
                 }
                 $pattern .= '/i';
                 $replacement = substr($ra[$i], 0, 2).'<x>'.substr($ra[$i], 2); // add in <> to nerf the tag
                 $val = preg_replace($pattern, $replacement, $val); // filter out the hex tags
                 if ($val_before == $val) {
                     // no replacements were made, so exit the loop
                     $found = false;
                 }
             }
         }
         // $val = trim($val);
         return $val;
    }
}
